/*
 * This file is part of the Sx Framework Library.
 * 
 * Copyright (C) 2013 University of Colorado Denver
 * <min.choi@ucdenver.edu> <shane.transue@ucdenver.edu>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 */
#include <sxBinaryFileReader.h>
#include <iostream>

const static char NULL_CHAR = '\0';

Sx::File::BinaryFileReader::BinaryFileReader() {}

Sx::File::BinaryFileReader::BinaryFileReader(const BinaryFileReader&) {}

Sx::File::BinaryFileReader::~BinaryFileReader() {
	if ( this->file.is_open() == true ) this->file.close();
}

bool Sx::File::BinaryFileReader::open(const String& fileName) {
	if ( this->file.is_open() == true ) this->file.close();
	this->file.open(fileName.toAscii().constData(), std::ios::in | std::ios::binary);
	return true;
}

bool Sx::File::BinaryFileReader::read(char& byte) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(&byte, sizeof(char));
	return true;
}

bool Sx::File::BinaryFileReader::read(char* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(buffer, length);
	return true;
}

bool Sx::File::BinaryFileReader::read(short& value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(&value), sizeof(short));
	return true;
}

bool Sx::File::BinaryFileReader::read(short* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(buffer), sizeof(short) * length);
	return true;
}

bool Sx::File::BinaryFileReader::read(int& value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(&value), sizeof(int));
	return true;
}

bool Sx::File::BinaryFileReader::read(int* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(buffer), sizeof(int) * length);
	return true;
}

bool Sx::File::BinaryFileReader::read(long& value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(&value), sizeof(long));
	return true;
}

bool Sx::File::BinaryFileReader::read(long* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(buffer), sizeof(long) * length);
	return true;
}

bool Sx::File::BinaryFileReader::read(float& value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(&value), sizeof(float));
	return true;
}

bool Sx::File::BinaryFileReader::read(float* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(buffer), sizeof(float) * length);
	return true;
}

bool Sx::File::BinaryFileReader::read(double& value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(&value), sizeof(double));
	return true;
}

bool Sx::File::BinaryFileReader::read(double* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.read(reinterpret_cast<char*>(buffer), sizeof(double) * length);
	return true;
}

Sx::String Sx::File::BinaryFileReader::readString() {
	std::string result = std::string();
	char currentChar;
	do {
		this->read(currentChar);
		if ( currentChar != NULL_CHAR ) result.push_back(currentChar);
	}
	while ( currentChar != NULL_CHAR );
	return result;
}

Sx::String Sx::File::BinaryFileReader::readString(unsigned int length) {
	char* buffer = new char[length];
	this->read(buffer, length);
	std::string result = std::string(buffer);
	delete [] buffer;
	char null = '\0';
	this->read(null);
	return result;
}

char Sx::File::BinaryFileReader::readChar() {
	char value = '\0';
	this->read(value);
	return value;
}

short Sx::File::BinaryFileReader::readShort() {
	short value = 0;
	this->read(value);
	return value;
}

int Sx::File::BinaryFileReader::readInt() {
	int value = 0;
	this->read(value);
	return value;
}

long Sx::File::BinaryFileReader::readLong() {
	long value = 0;
	this->read(value);
	return value;
}

float Sx::File::BinaryFileReader::readFloat() {
	float value = 0.0f;
	this->read(value);
	return value;
}

double Sx::File::BinaryFileReader::readDouble() {
	double value = 0.0;
	this->read(value);
	return value;
}

bool Sx::File::BinaryFileReader::close() {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileReader:read] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.close();
	return true;
}

Sx::File::BinaryFileReader& Sx::File::BinaryFileReader::operator = (const BinaryFileReader&) {
	return *this;
}
